# -*-mode:makefile; coding:utf-8-*-
#-----------makefile for XBase Master-------------

COMMONDIR:=common/ ../common/
SERVERDIR:=server/

OBJDIR:=bin/
SERVER_TARGET:=XBaseMaster.out
TESTDIR:=test/ logreader/ gfs_test/
TEST_TARGET:=cmdtest.out logreader.out gfs_test.out
SRC_SUFFIX:=cpp c

EXTERN_INCLUDE:=
#-I../../depends/include -L../../depends/lib

  #use GFS
#GFS_FLAGS:=-DUSE_GFS
#-DGFS_RETRY_DISABLED
#GFS_LIB:=-lgfsclient -lxsocket -lxthread -lappframe -llog4cplus -lpthread

####以下是可选的编译参数
    #------use logger(-DLOGGER) or not
LOG:=-DLOGGER
    #------debug mode or not(-DNDEBUG)
#NDEBUG:=-DNDEBUG
    #------use gprof
#PG:=-pg
    #------use zlib
#ZIP:=-lz
    #------use  openssl(-lcrypto) or not
#CRYPTO:=-lcrypto
    #------use mysql(-lmysqlclient_r -lz) or not
MYSQL:=-lmysqlclient_r -lz
    #------use epoll(-DUSEEPOLL) or poll
EPOLL:=-DUSEEPOLL
  #program versions
DATE:=$(shell date +"%Y%m%d")
TIME:=$(shell date +"%H%M%S")
HVERSION:=-DPROGRAM_VERSION_HIGH=$(DATE)
LVERSION:=-DPROGRAM_VERSION_LOW=1$(TIME)-1000000
PROGRAMVERSION:=$(SERVERDIR)ProgramVersion

CC:=$(CXX)
INCLUDE:=-I./ -I/usr/local/mysql/include/
CXXFLAGS:=-Wall -g -O2 $(INCLUDE) $(LOG) $(NDEBUG) $(EPOLL) $(HVERSION) $(LVERSION) $(GFS_FLAGS) $(PG) -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64
LIB:=-L/usr/local/mysql/lib -L./lib $(EXTERN_INCLUDE) -lstdc++ -lpthread -lrt $(MYSQL) $(LOG4CLIB) $(ZIP) $(CRYPTO) $(GFS_LIB) -lboost_system -lboost_regex
CFLAGS:=$(CXXFLAGS)

####以下是一些有用的函数

#下面用$(1)代替$@的原因是，在规则依赖里，$@不起作用
#由每个TEST_TARGET文件名得到所需的.o文件列表
TEST_OBJS=$(filter $(dir $(1))%.o,$(TESTOBJ))

#创建每个TEST_TARGET的规则
define BUILD_TEST
$(1) : $$(COMMONOBJ) $$(call TEST_OBJS,$(1))
	$$(CXX) $$^ $$(CXXFLAGS) -o $$@ $$(LIB)
endef

#得到所有SRC_SUFFIX后缀的源代码文件
GETSRC=$(foreach dir,$(1),$(wildcard $(addprefix $(dir)*.,$(SRC_SUFFIX))))

#得到.o文件
GETOBJ=$(foreach suffix,$(SRC_SUFFIX),$(filter %.o,$($(1):.$(suffix)=.o)))

####以下是工程创建规则，请勿盲目修改

TESTSRC:=$(call GETSRC,$(TESTDIR))
SERVERSRC:=$(call GETSRC,$(SERVERDIR))
COMMONSRC:=$(call GETSRC,$(COMMONDIR)) ../common/tablet_name_parser.cpp

TESTOBJ:=$(call GETOBJ,TESTSRC)
SERVEROBJ:=$(call GETOBJ,SERVERSRC)
COMMONOBJ:=$(call GETOBJ,COMMONSRC)

TESTDEP:=$(TESTOBJ:.o=.d)
SERVERDEP:=$(SERVEROBJ:.o=.d)
COMMONDEP:=$(COMMONOBJ:.o=.d)

CXXFLAGS+=-MD

ULTIMATE_TARGET:=$(SERVER_TARGET).$(DATE).$(TIME)
TEST_TARGET_LIST:=$(join $(TESTDIR),$(TEST_TARGET))

all: $(OBJDIR)$(SERVER_TARGET)

link: all
	@echo $(SERVER_TARGET) -\> $(ULTIMATE_TARGET)
	@mv $(OBJDIR)$(SERVER_TARGET) $(OBJDIR)$(ULTIMATE_TARGET)
	@ln -sf $(ULTIMATE_TARGET) $(OBJDIR)$(SERVER_TARGET)

$(OBJDIR)$(SERVER_TARGET) : $(COMMONOBJ) $(SERVEROBJ)
	$(CXX) $(CXXFLAGS) $^ -o $@ $(LIB)

test: $(TEST_TARGET_LIST)

$(foreach target,$(TEST_TARGET_LIST),$(eval $(call BUILD_TEST,$(target))))

$(PROGRAMVERSION).o : force

force : ;

commonobj : $(COMMONOBJ)

serverobj : $(SERVEROBJ)

testobj : $(TESTOBJ)

cleanobj : 
	$(RM) $(foreach dir,$(COMMONDIR),$(dir)*.o)
	$(RM) $(foreach dir,$(SERVERDIR),$(dir)*.o)
	$(RM) $(foreach dir,$(TESTDIR),$(dir)*.o)

cleandep : 
	$(RM) *.d
	$(RM) $(foreach dir,$(COMMONDIR),$(dir)*.d)
	$(RM) $(foreach dir,$(SERVERDIR),$(dir)*.d)
	$(RM) $(foreach dir,$(TESTDIR),$(dir)*.d)

cleandist : cleanobj cleandep

clean : cleandist
	$(RM) $(OBJDIR)$(SERVER_TARGET)
	$(RM) $(TEST_TARGET_LIST)

love: clean all

sinclude $(SERVERDEP) $(COMMONDEP) $(TESTDEP)

.PHONY : all link test force commonobj serverobj testobj cleanobj cleandep clean love  

